/* * xmlData class. * Provides a mechanism to retrieve an XML document from the server and then extract its data. * * As a first it tries to use the XML DOM model for document retrieval. * Failing that, we revert to using the XMLHTTP model. */ /* * Constants for the XML DOM state changes. */ var XML_UNINITIALIZED = 0; var XML_LOADING = 1; var XML_LOADED = 2; var XML_INTERACTIVE = 3; var XML_COMPLETED = 4; /* * xmlDataObject_getXMLElementData() * * Use the W3C DOM method for finding a tag and * returning the data content. */ function xmlDataObject_getXMLElementData(tag_name) { /* * Slight difference depending on Mozilla/IE and Opera on how we get the XML elements */ var xmlDocInstance = this.xmlDoc; if (typeof this.xmlDoc.load == "undefined") { /* * Opera (and others of this type) have their XML document stored in a responseXML property */ xmlDocInstance = this.xmlDoc.responseXML; } else { /* * Mozilla and IE XML DOM have a parser status variable */ if ((xmlDocInstance.parseError != null) && (xmlDocInstance.parseError.errorCode != 0)) { return null; } } var tag = xmlDocInstance.getElementsByTagName(tag_name); if (tag == null) { return null; } if (tag.length == 0) { return null; } var node = tag[0].firstChild; if ((node == null) || (node.nodeValue == null)) { return null; } return node.nodeValue; } /* * xmlDataObject_createXMLDocument() * Creates/Recreates the object used to retrieve the XML resource */ function xmlDataObject_createXMLDocument() { /* * Destroy any previous document */ if (this.xmlDoc != null) { delete this.xmlDoc; this.xmlDoc = null; this.operaRepeatedCompletionCallBugFix = false; } /* * Create a variable that _is_ this object so that the anonymous * functions can access it */ var xmlDataInstance = this; /* * Create an XML DOM for retrieving the data */ if ((typeof document.implementation == "object") && (typeof document.implementation.createDocument == "function")) { /* * This is Mozilla (and others) compatible and is the preferred standard for retrieving an XML document. */ this.xmlDoc = document.implementation.createDocument("", "", null); /* * Opera browsers do not support this method, however, even though they say they can! */ if (typeof this.xmlDoc.load != "undefined") { /* * Supported properly */ this.xmlDoc.onload = function () { /* * Loading can complete in error! * If there is no data then ignore (wait for timeout). */ if (xmlDataInstance.xmlDoc.firstChild == null) { return; } /* * Clear the timeout and signal success */ window.clearTimeout(xmlDataInstance.timeoutId); xmlDataInstance.dataReadyFunc(xmlDataInstance); } return; } /* * Drop through and try Microsoft and Opera */ } /* * Try IE and Opera */ if (window.ActiveXObject) { /* * This is Microsofts way */ this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); if (this.xmlDoc == null) { /* * Try the HTTP model */ this.xmlDoc = new ActiveXObject("MSXML2.XMLHTTP"); } } else if (window.XMLHttpRequest) { /* * Opera 7.6+ and others */ this.xmlDoc = new XMLHttpRequest(); } if (this.xmlDoc == null) { /* * Old unsupported browser */ alert("Your browser does not support XML retrieval"); return; } this.xmlDoc.onreadystatechange = function () { if (xmlDataInstance.xmlDoc.readyState == XML_COMPLETED) { if (xmlDataInstance.operaRepeatedCompletionCallBugFix) { return; } /* * Opera browsers have a repeated call bug */ xmlDataInstance.operaRepeatedCompletionCallBugFix = true; /* * Opera browsers have a status field to indicate the HTTP response */ if (typeof xmlDataInstance.xmlDoc.status != "undefined") { if (xmlDataInstance.xmlDoc.status != 200) { /* * Rely on timeout */ return; } } else { /* * IE can still signal 'complete' even in error */ if (xmlDataInstance.xmlDoc.firstChild == null) { /* * Rely on timeout */ return; } } window.clearTimeout(xmlDataInstance.timeoutId); xmlDataInstance.dataReadyFunc(xmlDataInstance); } } } /* * xmlDataObject_retrieveData() * Begin retrieval. */ function xmlDataObject_retrieveData() { /* * Create the document object that will retrieve the requested doc * NOTE: Any previous one is destroyed. */ this.createXMLDocument(); /* * Create a local variable that is an anonumous function to be evaluated when the timeout occurs. * The anonymous function will have access to the xmlDataObject instance! */ var xmlDataInstance = this; var fnx = function() { /* * Re-create the document (more importantly: destroy the existing one) */ xmlDataInstance.createXMLDocument(); /* * Invoke the timeout callback function */ xmlDataInstance.dataTimeoutFunc(xmlDataInstance); } this.timeoutId = window.setTimeout(fnx, this.timeoutMillis); /* * Start the loading of the resource */ if (typeof this.xmlDoc.load != "undefined") { /* * Microsoft and Mozilla using XML model */ this.xmlDoc.async="true"; this.xmlDoc.load(this.dataURL); return; } /* * Opera and old IE XMLHTTPRequest */ this.xmlDoc.open('GET', this.dataURL, true); this.xmlDoc.send(); } /* * xmlDataObject() * Create an XML data object. * * Used to retrieve data from the server in XML format. * The given function is invoked when the data is retrieved. */ function xmlDataObject(dataReadyFunc, dataTimeoutFunc, timeoutMillis, dataURL) { /* * Initialise properties. */ this.dataReadyFunc = dataReadyFunc; this.dataTimeoutFunc = dataTimeoutFunc; this.dataURL = dataURL; this.timeoutMillis = timeoutMillis; this.timeoutId = 0; this.xmlDoc = null; this.operaRepeatedCompletionCallBugFix = false; /* To fix opera bug on getting called back more than once */ /* * Initialize the public methods */ this.retrieveData = xmlDataObject_retrieveData; this.getXMLElementData = xmlDataObject_getXMLElementData; /* * Initialise private methods */ this.createXMLDocument = xmlDataObject_createXMLDocument; }